<?php
include_once "para.inc";
include_once "errlog.inc";
include_once "sock.inc";
include_once "errcode.inc";

class soar
{/*{{{*/
    private static $TIMEOUT=60;
    private $sock;
    private $ip;
    private $port;

    public $view=array();

    public function __construct()
    {/*{{{*/
        $this->sock=null;
        if(($location=get_cfg_var("soar_svc_addr")))
        {
            $addr=explode(":", $location);
            $this->ip=gethostbyname($addr[0]);
            $this->port=intval($addr[1]);
        }
    }/*}}}*/

    public function __destruct()
    {/*{{{*/
        if($this->sock)
        {
            socket_close($this->sock);
        }
    }/*}}}*/

    private function _call($request, &$respond)
    {/*{{{*/
        $respond="";
        if($this->sock == null)
        {
            $timeout=5;
            if(sock::connect($this->ip, $this->port, $timeout,
                        $this->sock) == false)
            {
                errlog::write("%s line(%d): ".
                    "connect to svcenv fail",
                    basename(__FILE__), __LINE__);
                para::put_item($respond, SOAR_ERR_COMM_FAIL);
                return false;
            }
        }

        $timeout=self::$TIMEOUT;
        if(sock::send($this->sock, $request, $timeout) == false)
        {
            errlog::write("%s line(%d): ".
                    "send svc(%s) request to svcenv fail",
                    basename(__FILE__), __LINE__, $svc);
            para::put_item($respond, SOAR_ERR_COMM_FAIL);
            return false;
        }
        if(sock::recv($this->sock, $respond, $timeout) == false)
        {
            errlog::write("%s line(%d): ".
                    "recv svc(%s) response to svcenv fail",
                    basename(__FILE__), __LINE__, $svc);
            para::put_item($respond, SOAR_ERR_COMM_FAIL);  
            return false;
        }

        return true;
    }/*}}}*/

    public function call($svc, $request, &$respond)
    {/*{{{*/
        para::put_item($msg, "CALL", $svc);
        $msg.=$request;
        return self::_call($msg, $respond);
    }/*}}}*/

    public function callnode($node, $svc, $request, &$respond)
    {/*{{{*/
        para::put_item($msg, "CALLNODE", $node, $svc);
        $msg.=$request;
        return self::_call($msg, $respond);
    }/*}}}*/

    public function close()
    {/*{{{*/
        if($this->sock == null) return false;
        para::put_item($request, "CLOSE");
        $res=self::_call($request, $respond);
        socket_close($this->sock);
        $this->sock=null; 
    }/*}}}*/

    public function begin()
    {/*{{{*/
        if($this->sock)
        {
            errlog::write("%s line(%d): ".
                    "without ending former trans, begin new trans",
                    basename(__FILE__), __LINE__);
            socket_close($this->sock);
            $this->sock=null;
        }
    }/*}}}*/

    public function commit()
    {/*{{{*/
        if($this->sock == null) return false;
        para::put_item($request, "COMMIT");
        return self::_call($request, $respond);
        //socket_close($this->sock);
        //$this->sock=null; 
    }/*}}}*/

    public function abort()
    {/*{{{*/
        if($this->sock == null) return false;
        para::put_item($request, "ABORT");
        return self::_call($request, $respond);
        //socket_close($this->sock);
        //$this->sock=null; 
    }/*}}}*/

    public function session()
    {/*{{{*/
        include "session.inc";
        $h=new session($this);
        return $h;
    }/*}}}*/

    public function secure()
    {/*{{{*/
        include "secure.inc";
        $h=new secure($this);
        return $h;
    }/*}}}*/

    public function mailfwd()
    {/*{{{*/
        include "mailfwd.inc";
        $h=new mailfwd($this);
        return $h;
    }/*}}}*/

    public function confirm()
    {/*{{{*/
        include "confirm.inc";
        $h=new confirm($this);
        return $h;
    }/*}}}*/
}/*}}}*/
?>
